package accounttaocan

import (
	"context"
	"database/sql"
	"fmt"
	"github.com/zeromicro/go-zero/core/stores/cache"
	"github.com/zeromicro/go-zero/core/stores/sqlx"
	"strings"
	"time"
)

var _ YunhuAccountTaocanModel = (*customYunhuAccountTaocanModel)(nil)

type (
	// YunhuAccountTaocanModel is an interface to be customized, add more methods here,
	// and implement the added methods in customYunhuAccountTaocanModel.
	YunhuAccountTaocanModel interface {
		yunhuAccountTaocanModel
		ListAccountIds(ctx context.Context, customerId int64, monthUse string) ([]*AccountTaocanModel, error)
		ListAccount(ctx context.Context, customerId int64, kind int64, accountIds []string, monthUse string) ([]*YunhuAccountTaocan, error)
		List(ctx context.Context, customerId int64, accountId int64, monthUse string, page int64, limit int64) ([]*YunhuAccountTaocan, error)
		Counts(ctx context.Context, customerId int64, accountId int64, monthUse string) (int64, error)
		BatchInsert(ctx context.Context, date []*YunhuAccountTaocan) error
		MinutesDeductUpdate(ctx context.Context, data *YunhuAccountTaocan) error
	}

	customYunhuAccountTaocanModel struct {
		*defaultYunhuAccountTaocanModel
	}

	AccountTaocanModel struct {
		AccountId int64 `db:"account_id"` // 座席ID
	}
)

func (m *customYunhuAccountTaocanModel) MinutesDeductUpdate(ctx context.Context, data *YunhuAccountTaocan) error {
	yunhuAccountTaocanCustomerIdAccountIdKindMonthUseKey := fmt.Sprintf("%s%v:%v:%v:%v", cacheYunhuAccountTaocanCustomerIdAccountIdMonthUseKindPrefix, data.CustomerId, data.AccountId, data.Kind, data.MonthUse)
	yunhuAccountTaocanIdKey := fmt.Sprintf("%s%v", cacheYunhuAccountTaocanIdPrefix, data.Id)
	_, err := m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
		query := fmt.Sprintf("update %s set number_use = ?, number_use_taowai = ? where `id` = ?", m.table)
		return conn.ExecCtx(ctx, query, data.NumberUse, data.NumberUseTaowai, data.Id)
	}, yunhuAccountTaocanCustomerIdAccountIdKindMonthUseKey, yunhuAccountTaocanIdKey)

	return err
}

func (m *customYunhuAccountTaocanModel) ListAccount(ctx context.Context, customerId int64, kind int64, accountIds []string, monthUse string) ([]*YunhuAccountTaocan, error) {

	var resp []*YunhuAccountTaocan
	query := fmt.Sprintf("select %s from %s where customer_id = ? and account_id in (%s) and  kind = ? and month_use = ? ", yunhuAccountTaocanRows, m.table, strings.Join(accountIds, ","))
	if err := m.QueryRowsNoCacheCtx(ctx, &resp, query, customerId, kind, monthUse); err != nil && err != ErrNotFound {
		return nil, err
	}

	return resp, nil
}

func (m *customYunhuAccountTaocanModel) ListAccountIds(ctx context.Context, customerId int64, monthUse string) ([]*AccountTaocanModel, error) {

	var resp []*AccountTaocanModel
	query := fmt.Sprintf("select %s from %s where customer_id = ? and month_use = ? ", yunhuAccountTaocanRows, m.table)
	if err := m.QueryRowsNoCacheCtx(ctx, &resp, query, customerId, monthUse); err != nil && err != ErrNotFound {
		return nil, err
	}

	return resp, nil
}

func (m *customYunhuAccountTaocanModel) List(ctx context.Context, customerId int64, accountId int64, monthUse string, page int64, limit int64) ([]*YunhuAccountTaocan, error) {
	var sqlWhere string = m.getWhere(customerId, accountId, monthUse)
	var resp []*YunhuAccountTaocan
	query := fmt.Sprintf("select %s from %s %s order by id desc limit ?,?", yunhuAccountTaocanRows, m.table, sqlWhere)
	if err := m.QueryRowsNoCacheCtx(ctx, &resp, query, (page-1)*limit, limit); err != nil && err != ErrNotFound {
		return nil, err
	}

	return resp, nil
}

func (m *customYunhuAccountTaocanModel) Counts(ctx context.Context, customerId int64, accountId int64, monthUse string) (int64, error) {
	var sqlWhere string = m.getWhere(customerId, accountId, monthUse)
	//先统计数量
	var countTotal Counts
	var sql string = fmt.Sprintf("select count(*) as total from %s %s", m.table, sqlWhere)
	var err error = m.QueryRowNoCacheCtx(ctx, &countTotal, sql)
	return countTotal.Total, err
}

// 管理员列表条件
func (m *customYunhuAccountTaocanModel) getWhere(customerId int64, accountId int64, monthUse string) string {
	var sqlWhere []string = make([]string, 0)

	if accountId > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" account_id = %d ", accountId))
	}

	if customerId > 0 {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" customer_id = %d ", customerId))
	}

	if monthUse != "" {
		sqlWhere = append(sqlWhere, fmt.Sprintf(" month_use = '%s' ", monthUse))
	}

	if len(sqlWhere) == 0 {
		return ""
	}

	var sqlStr string = strings.Join(sqlWhere, " and ")
	if sqlStr != "" {
		sqlStr = " where " + sqlStr
	}

	return sqlStr
}

// 批量插入
func (m *customYunhuAccountTaocanModel) BatchInsert(ctx context.Context, taocanList []*YunhuAccountTaocan) error {
	var nowtimeInt int64 = time.Now().Local().Unix()
	var sql string = "insert into jxg_yunhu_account_taocan (customer_id,account_id,kind,taocan_name,number,price,effective_time,month_use,pay_type,create_time) values "
	var vals []string = make([]string, len(taocanList))
	for k, _ := range taocanList {
		vals[k] = fmt.Sprintf("(%d,%d,%d,%d,%d,'%s',%d,%f,%d,'%s',%d,%d,%d)", taocanList[k].CustomerId, taocanList[k].AccountId, taocanList[k].Kind, taocanList[k].TaocanName, taocanList[k].Number, taocanList[k].Price, taocanList[k].EffectiveTime, taocanList[k].MonthUse, taocanList[k].PayType, nowtimeInt)
	}

	var taocanSql string = fmt.Sprintf("%s %s", sql, strings.Join(vals, ","))

	_, err := m.ExecNoCacheCtx(ctx, taocanSql)
	return err
}

// NewYunhuAccountTaocanModel returns a model for the database table.
func NewYunhuAccountTaocanModel(conn sqlx.SqlConn, c cache.CacheConf, opts ...cache.Option) YunhuAccountTaocanModel {
	return &customYunhuAccountTaocanModel{
		defaultYunhuAccountTaocanModel: newYunhuAccountTaocanModel(conn, c, opts...),
	}
}
